Skip to content

Exercises

A List component

Let's suppose we're building a List component.

There are two types of lists in HTML: unordered lists (<ul>) and ordered lists (<ol>). Our List component should be able to render either.

Acceptance Criteria:

  • The consumer should be able to specify whether they want to render an ol or a ul, by passing a prop to List.
  • The component should restrict the user so that it can only render ul and ol (and not, for example, p or button).

Code Playground

import React from 'react';

import styles from './List.module.css';

function List({ className = '', children, ...delegated }) {
return (
<ul
{...delegated}
className={`${styles.wrapper} ${className}`}
>
{children}
</ul>
)
}

export default List;

Solution:

In this solution, we use object destructuring to extract the as prop, and rename it to Tag. You can learn more about this syntax in the “Object Destructuring” reference lesson 👀.

Customized heading levels

HTML gives us 6 different heading tags, <h1> through <h6>.

Some developers believe that you're supposed to pick the one based on the size of the text: <h1> for large headings, <h6> for small ones. But this isn't true. We can use CSS to make any heading tag any size. We should never pick HTML tags based on their aesthetics, we should pick them based on their semantics!

Instead, the goal with the heading tags is to organize the content as a hierarchy.

For example, consider this article from Wikipedia:

Screenshot of the George Mouzalon Wikipedia article

Imagine you were responsible for generating the "table of contents" for this page. You'd probably structure it something like this:

  • George Mouzalon
    • Biography
      • Early life and service under Theodore II
      • Appointment as regent and assassination
    • Treatment by Historians (not pictured, below the fold)

The page is all about “George Mouzalon”. But that page is split into a few chunks, like the biography, the treatment by historians...

And within those sections, we have subsections!

Documents tend to be hierarchical like this. In HTML, the heading levels are meant to represent this hierarchy.

Inspecting the HTML, we see that Wikipedia has chosen the following heading levels:

Screenshot of the George Mouzalon Wikipedia article, with boxes drawn around each section

Every page should have a single <h1> that covers the entire page (eg. the title of a blog post, the headline of a news article). Each section is labeled with <h2>, each sub-section with <h3>, each sub-sub-section with <h4>, etc.

This presents a bit of a challenge for us React developers.

For example: Suppose we have a component like this:

function SectionWithHeading({ heading, children, ...delegated }) {
return (
<section {...delegated}>
<h2>{heading}</h2>
{children}
</section>
);
}

This component bundles together a chunk of stuff with a heading. But it hardcodes an <h2> tag, which might not always be the right heading level!

Let's fix this code using polymorphism.

Acceptance Criteria:

  • Update the <SectionWithHeading> component so that it allows the consumer to specify the heading level.
  • In App.js, add a prop to each instance to set the heading level to the correct value.
  • When properly set, styles will be applied automatically to the heading tags, and the final result should look like this:
Screenshot of the final version, with Wikipedia-style headings

Note: Depending on your operating system, the serif headings might look a bit different. This is due to each operating system using a different default serif font.

Code Playground

import React from 'react';

function SectionWithHeading({ title, children }) {
return (
<section>
<h2>{title}</h2>
{children}
</section>
);
}

export default SectionWithHeading;

Solution:

Correction: In the solution, we throw an error when the level is less than 0. Given that <h0> is not a valid tag, it should actually throw when level is less than 1, not 0. This correction has been applied to the solution below: